package com.blockmeta.bbs.businesslibrary.util.navigation;

import android.text.TextUtils;

import com.blockmeta.bbs.businesslibrary.util.navigation.impl.AMAStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.ActivityStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.BBSArticleStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.BBSDetailStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.BBSDocStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.BBSForumStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.BBSTopicStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.BBSTutorialStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.Chain8Strategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.ChainThingStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.ChainTopicStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.DropHappyStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.FlashStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.GoldCoinsMallStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.IMChatGroupStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.IMChatStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.IMCircleDetailStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.IMFriendStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.IMPersonHomeStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.IMPersonalHomeStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.InviteStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.MarketCoinF10Strategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.MarketCoinStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.MarketKlineStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.MessageStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.NewsDetailStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.NewsStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.SettingUserInfoStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.TaskCenterStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.WebStrategy;
import com.blockmeta.bbs.businesslibrary.util.navigation.impl.WeekTopicStrategy;

import java.util.HashMap;

/**
 * @author AirThor
 * @date 2019/7/24.
 */
public class StrategyFactory {

    private StrategyFactory(){}

    /** 缓存策略类实例，由于一个策略可能要多次使用，如果不做缓存，每次都要通过反射实例化一个，内存中的无用对象也会
     * 越来越多
     */
    private static HashMap<String,IDeepLinkStrategy> strategyCaches = new HashMap<>();

    private static class StrategyFactoryHolder{
        public static final StrategyFactory INSTANCE = new StrategyFactory();
    }

    public static StrategyFactory getInstance(){
        return StrategyFactoryHolder.INSTANCE;
    }

    private static HashMap<String,String> classMap = new HashMap<>();

    static {
        classMap.put("news", NewsStrategy.class.getName());
        classMap.put("news/detail", NewsDetailStrategy.class.getName());
        classMap.put("news/topic", ChainTopicStrategy.class.getName());
        classMap.put("news/weekly", WeekTopicStrategy.class.getName());
        classMap.put("flash", FlashStrategy.class.getName());
        classMap.put("bbs/detail", BBSDetailStrategy.class.getName());
        classMap.put("bbs/article", BBSArticleStrategy.class.getName());
        classMap.put("bbs/topic", BBSTopicStrategy.class.getName());
        classMap.put("bbs/forum", BBSForumStrategy.class.getName());
        classMap.put("bbs/doc", BBSDocStrategy.class.getName());
        classMap.put("bbs/tutorial", BBSTutorialStrategy.class.getName());
        classMap.put("ama", AMAStrategy.class.getName());
        classMap.put("activity", ActivityStrategy.class.getName());
        classMap.put("drop_happy", DropHappyStrategy.class.getName());
        classMap.put("web", WebStrategy.class.getName());
        classMap.put("invite", InviteStrategy.class.getName());
        classMap.put("message/system", MessageStrategy.class.getName());
        classMap.put("message/user", MessageStrategy.class.getName());
        classMap.put("market/kline", MarketKlineStrategy.class.getName());
        classMap.put("market/coin", MarketCoinStrategy.class.getName());
        classMap.put("market/coinf10", MarketCoinF10Strategy.class.getName());
        classMap.put("settingUserInfo", SettingUserInfoStrategy.class.getName());
        classMap.put("taskCenter", TaskCenterStrategy.class.getName());
        classMap.put("goldCoinsMall", GoldCoinsMallStrategy.class.getName());
        classMap.put("chain8", Chain8Strategy.class.getName());
        classMap.put("im/chat", IMChatStrategy.class.getName());
        classMap.put("im/chatgroup", IMChatGroupStrategy.class.getName());
        classMap.put("im/chatgroup_detail", IMCircleDetailStrategy.class.getName());
        classMap.put("im/friend", IMFriendStrategy.class.getName());
        classMap.put("mall/item", ChainThingStrategy.class.getName());
        classMap.put("im/user", IMPersonHomeStrategy.class.getName());
    }

    public IDeepLinkStrategy creator(String key){
        //如果实例已经存在则直接取出
        if (strategyCaches.get(key) != null){
            return strategyCaches.get(key);
        }
        //实例不存在通过策略类名反射得到实例并缓存到strategyCaches里面
        String className = classMap.get(key);
        if (TextUtils.isEmpty(className)){
            className = WebStrategy.class.getName();
        }
        try {
            IDeepLinkStrategy iDeepLinkStrategy = (IDeepLinkStrategy) Class.forName(className).newInstance();
            strategyCaches.put(key,iDeepLinkStrategy);
            return iDeepLinkStrategy;
        } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
            e.printStackTrace();
            return null;
        }
    }
}
